package com.guducat.collegeWeb.service;

import cn.dev33.satoken.stp.StpUtil;
import com.guducat.collegeWeb.dto.request.UserDataSyncDTO;
import com.guducat.collegeWeb.dto.response.UserDataSyncResultDTO;
import com.guducat.collegeWeb.entity.UserData;
import com.guducat.collegeWeb.entity.UserDataSyncLog;
import com.guducat.collegeWeb.mapper.UserDataMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户数据同步服务
 */
@Service
public class UserDataSyncService {

    private final UserDataMapper userDataMapper;

    @Autowired
    public UserDataSyncService(UserDataMapper userDataMapper) {
        this.userDataMapper = userDataMapper;
    }

    /**
     * 处理用户数据同步请求
     */
    @Transactional
    public UserDataSyncResultDTO syncUserData(UserDataSyncDTO syncRequest) {
        // 获取当前登录用户ID
        Integer userId = StpUtil.getLoginIdAsInt();
        
        // 记录同步开始日志
        UserDataSyncLog syncLog = new UserDataSyncLog(userId, syncRequest.getSyncType(), 
                String.join(",", syncRequest.getDataTypes()), syncRequest.getClientVersion());
        userDataMapper.insertSyncLog(syncLog);

        try {
            UserDataSyncResultDTO result;
            
            switch (syncRequest.getSyncType().toLowerCase()) {
                case "upload":
                    result = handleUpload(userId, syncRequest, syncLog);
                    break;
                case "download":
                    result = handleDownload(userId, syncRequest, syncLog);
                    break;
                case "merge":
                    result = handleMerge(userId, syncRequest, syncLog);
                    break;
                case "delete":
                    result = handleDelete(userId, syncRequest, syncLog);
                    break;
                default:
                    throw new IllegalArgumentException("不支持的同步类型: " + syncRequest.getSyncType());
            }

            // 更新同步日志为成功
            syncLog.markSuccess();
            syncLog.setStats(result.getTotalCount(), result.getSuccessCount(), result.getConflictCount());
            userDataMapper.updateSyncLog(syncLog);

            return result;

        } catch (Exception e) {
            // 更新同步日志为失败
            syncLog.markFailed(e.getMessage());
            userDataMapper.updateSyncLog(syncLog);
            
            return UserDataSyncResultDTO.failure(syncRequest.getSyncType(), e.getMessage());
        }
    }

    /**
     * 处理上传同步
     */
    private UserDataSyncResultDTO handleUpload(Integer userId, UserDataSyncDTO syncRequest, UserDataSyncLog syncLog) {
        List<UserDataSyncDTO.UserDataItemDTO> dataItems = syncRequest.getDataItems();
        if (dataItems == null || dataItems.isEmpty()) {
            return UserDataSyncResultDTO.success(syncRequest.getSyncType(), 0, 0);
        }

        int totalCount = dataItems.size();
        int successCount = 0;
        int conflictCount = 0;
        List<UserDataSyncResultDTO.ConflictDataDTO> conflicts = new ArrayList<>();
        List<UserDataSyncResultDTO.DataTypeSyncDetail> syncDetails = new ArrayList<>();

        // 按数据类型分组处理
        for (String dataType : syncRequest.getDataTypes()) {
            List<UserDataSyncDTO.UserDataItemDTO> typeItems = dataItems.stream()
                    .filter(item -> dataType.equals(item.getDataType()))
                    .collect(Collectors.toList());

            UserDataSyncResultDTO.DataTypeSyncDetail detail = processDataTypeUpload(
                    userId, dataType, typeItems, syncRequest.getSyncConfig());
            
            syncDetails.add(detail);
            successCount += detail.getSuccessCount();
            conflictCount += detail.getConflictCount();
        }

        UserDataSyncResultDTO result = UserDataSyncResultDTO.success(syncRequest.getSyncType(), totalCount, successCount);
        result.setConflictCount(conflictCount);
        result.setSyncDetails(syncDetails);
        result.setConflicts(conflicts);

        return result;
    }

    /**
     * 处理下载同步
     */
    private UserDataSyncResultDTO handleDownload(Integer userId, UserDataSyncDTO syncRequest, UserDataSyncLog syncLog) {
        List<UserDataSyncResultDTO.UserDataItemDTO> downloadData = new ArrayList<>();
        List<UserDataSyncResultDTO.DataTypeSyncDetail> syncDetails = new ArrayList<>();

        for (String dataType : syncRequest.getDataTypes()) {
            List<UserData> userDataList = userDataMapper.findByUserIdAndType(userId, dataType);
            
            List<UserDataSyncResultDTO.UserDataItemDTO> typeData = userDataList.stream()
                    .map(this::convertToDTO)
                    .collect(Collectors.toList());
            
            downloadData.addAll(typeData);

            UserDataSyncResultDTO.DataTypeSyncDetail detail = new UserDataSyncResultDTO.DataTypeSyncDetail();
            detail.setDataType(dataType);
            detail.setProcessedCount(typeData.size());
            detail.setSuccessCount(typeData.size());
            detail.setConflictCount(0);
            detail.setFailedCount(0);
            
            syncDetails.add(detail);
        }

        UserDataSyncResultDTO result = UserDataSyncResultDTO.success(syncRequest.getSyncType(), downloadData.size(), downloadData.size());
        result.setDownloadData(downloadData);
        result.setSyncDetails(syncDetails);

        return result;
    }

    /**
     * 处理合并同步
     */
    private UserDataSyncResultDTO handleMerge(Integer userId, UserDataSyncDTO syncRequest, UserDataSyncLog syncLog) {
        // 合并同步：先下载服务器数据，然后上传客户端数据，处理冲突
        UserDataSyncResultDTO downloadResult = handleDownload(userId, syncRequest, syncLog);
        UserDataSyncResultDTO uploadResult = handleUpload(userId, syncRequest, syncLog);

        // 合并结果
        UserDataSyncResultDTO result = new UserDataSyncResultDTO();
        result.setSuccess(downloadResult.getSuccess() && uploadResult.getSuccess());
        result.setSyncType(syncRequest.getSyncType());
        result.setSyncTime(LocalDateTime.now());
        result.setTotalCount(downloadResult.getTotalCount() + uploadResult.getTotalCount());
        result.setSuccessCount(downloadResult.getSuccessCount() + uploadResult.getSuccessCount());
        result.setConflictCount(uploadResult.getConflictCount());
        result.setFailedCount(uploadResult.getFailedCount());
        result.setDownloadData(downloadResult.getDownloadData());
        result.setConflicts(uploadResult.getConflicts());

        return result;
    }

    /**
     * 处理特定数据类型的上传
     */
    private UserDataSyncResultDTO.DataTypeSyncDetail processDataTypeUpload(Integer userId, String dataType, 
            List<UserDataSyncDTO.UserDataItemDTO> items, UserDataSyncDTO.SyncConfigDTO config) {
        
        UserDataSyncResultDTO.DataTypeSyncDetail detail = new UserDataSyncResultDTO.DataTypeSyncDetail();
        detail.setDataType(dataType);
        detail.setProcessedCount(items.size());
        
        int successCount = 0;
        int conflictCount = 0;
        List<String> errors = new ArrayList<>();

        for (UserDataSyncDTO.UserDataItemDTO item : items) {
            try {
                // 检查是否已存在
                boolean exists = userDataMapper.existsByUserIdAndTypeAndNews(userId, dataType, item.getNewsId());

                if (exists) {
                    // 处理冲突
                    if (config != null && config.getOverwriteConflicts()) {
                        // 覆盖现有数据
                        UserData existingData = userDataMapper.findByUserIdAndTypeAndNews(userId, dataType, item.getNewsId());
                        updateUserDataFromDTO(existingData, item);
                        userDataMapper.updateUserData(existingData);
                        successCount++;
                    } else {
                        // 跳过冲突数据
                        conflictCount++;
                    }
                } else {
                    // 插入新数据
                    UserData userData = convertFromDTO(userId, item);
                    userDataMapper.insertUserData(userData);
                    successCount++;
                }
            } catch (Exception e) {
                errors.add("处理文章 " + item.getNewsId() + " 时出错: " + e.getMessage());
            }
        }

        detail.setSuccessCount(successCount);
        detail.setConflictCount(conflictCount);
        detail.setFailedCount(items.size() - successCount - conflictCount);
        detail.setErrors(errors);

        return detail;
    }

    /**
     * 转换实体为DTO
     */
    private UserDataSyncResultDTO.UserDataItemDTO convertToDTO(UserData userData) {
        UserDataSyncResultDTO.UserDataItemDTO dto = new UserDataSyncResultDTO.UserDataItemDTO();
        dto.setDataType(userData.getDataType());
        dto.setNewsId(userData.getNewsId());
        dto.setNewsTitle(userData.getNewsTitle());
        dto.setNewsUrl(userData.getNewsUrl());
        dto.setNewsCategory(userData.getNewsCategory());
        dto.setNewsSection(userData.getNewsSection());
        dto.setExtraData(userData.getExtraData());
        dto.setCreateTime(userData.getCreateTime());
        dto.setUpdateTime(userData.getUpdateTime());
        return dto;
    }

    /**
     * 转换DTO为实体
     */
    private UserData convertFromDTO(Integer userId, UserDataSyncDTO.UserDataItemDTO dto) {
        UserData userData = new UserData();
        userData.setUserId(userId);
        userData.setDataType(dto.getDataType());
        userData.setNewsId(dto.getNewsId());
        userData.setNewsTitle(dto.getNewsTitle());
        userData.setNewsUrl(dto.getNewsUrl());
        userData.setNewsCategory(dto.getNewsCategory());
        userData.setNewsSection(dto.getNewsSection());
        userData.setExtraData(dto.getExtraData());
        userData.setCreateTime(dto.getCreateTime() != null ? dto.getCreateTime() : LocalDateTime.now());
        userData.setUpdateTime(LocalDateTime.now());
        return userData;
    }

    /**
     * 从DTO更新实体
     */
    private void updateUserDataFromDTO(UserData userData, UserDataSyncDTO.UserDataItemDTO dto) {
        userData.setNewsTitle(dto.getNewsTitle());
        userData.setNewsUrl(dto.getNewsUrl());
        userData.setNewsCategory(dto.getNewsCategory());
        userData.setNewsSection(dto.getNewsSection());
        userData.setExtraData(dto.getExtraData());
        userData.setUpdateTime(LocalDateTime.now());
    }

    /**
     * 获取用户数据统计
     */
    public List<java.util.Map<String, Object>> getUserDataStats(Integer userId) {
        return userDataMapper.getUserDataStats(userId);
    }

    /**
     * 清理过期历史记录
     */
    public int cleanExpiredHistory(Integer userId, Integer keepDays) {
        return userDataMapper.cleanExpiredHistory(userId, keepDays);
    }

    /**
     * 处理删除同步
     */
    private UserDataSyncResultDTO handleDelete(Integer userId, UserDataSyncDTO syncRequest, UserDataSyncLog syncLog) {
        List<UserDataSyncDTO.UserDataItemDTO> dataItems = syncRequest.getDataItems();
        if (dataItems == null || dataItems.isEmpty()) {
            UserDataSyncResultDTO errorResult = new UserDataSyncResultDTO();
            errorResult.setSuccess(false);
            errorResult.setErrorMessage("删除数据项不能为空");
            errorResult.setSyncType(syncRequest.getSyncType());
            errorResult.setSyncTime(LocalDateTime.now());
            return errorResult;
        }

        int totalCount = dataItems.size();
        int successCount = 0;
        List<String> errors = new ArrayList<>();
        List<UserDataSyncResultDTO.DataTypeSyncDetail> syncDetails = new ArrayList<>();

        // 按数据类型分组处理删除
        for (String dataType : syncRequest.getDataTypes()) {
            List<UserDataSyncDTO.UserDataItemDTO> typeItems = dataItems.stream()
                    .filter(item -> dataType.equals(item.getDataType()))
                    .collect(Collectors.toList());

            UserDataSyncResultDTO.DataTypeSyncDetail detail = processDataTypeDelete(
                    userId, dataType, typeItems);

            syncDetails.add(detail);
            successCount += detail.getSuccessCount();
        }

        UserDataSyncResultDTO result = new UserDataSyncResultDTO();
        result.setSuccess(true);
        result.setSyncType(syncRequest.getSyncType());
        result.setSyncTime(LocalDateTime.now());
        result.setTotalCount(totalCount);
        result.setSuccessCount(successCount);
        result.setFailedCount(totalCount - successCount);
        result.setSyncDetails(syncDetails);

        if (!errors.isEmpty()) {
            result.setErrorMessage(String.join("; ", errors));
        }

        return result;
    }

    /**
     * 处理特定数据类型的删除
     */
    private UserDataSyncResultDTO.DataTypeSyncDetail processDataTypeDelete(Integer userId, String dataType,
            List<UserDataSyncDTO.UserDataItemDTO> items) {

        UserDataSyncResultDTO.DataTypeSyncDetail detail = new UserDataSyncResultDTO.DataTypeSyncDetail();
        detail.setDataType(dataType);
        detail.setProcessedCount(items.size());

        int successCount = 0;
        List<String> errors = new ArrayList<>();

        for (UserDataSyncDTO.UserDataItemDTO item : items) {
            try {
                // 检查数据是否存在
                boolean exists = userDataMapper.existsByUserIdAndTypeAndNews(userId, dataType, item.getNewsId());

                if (exists) {
                    // 执行删除操作
                    int deletedRows = userDataMapper.deleteUserDataByNews(userId, dataType, item.getNewsId());
                    if (deletedRows > 0) {
                        successCount++;
                        System.out.println("成功删除用户数据: userId=" + userId + ", dataType=" + dataType + ", newsId=" + item.getNewsId());
                    } else {
                        errors.add("删除文章 " + item.getNewsId() + " 失败: 未删除任何记录");
                    }
                } else {
                    // 数据不存在，视为删除成功
                    successCount++;
                    System.out.println("数据不存在，视为删除成功: userId=" + userId + ", dataType=" + dataType + ", newsId=" + item.getNewsId());
                }
            } catch (Exception e) {
                errors.add("删除文章 " + item.getNewsId() + " 时出错: " + e.getMessage());
                System.err.println("删除用户数据时发生异常: " + e.getMessage());
                e.printStackTrace();
            }
        }

        detail.setSuccessCount(successCount);
        detail.setConflictCount(0); // 删除操作没有冲突
        detail.setFailedCount(items.size() - successCount);
        detail.setErrors(errors);

        return detail;
    }
}
